package com.meimeixia.pattern.singleton.demo5;

/**
 * 静态内部类
 * @author: t-zhijiang.zhao
 * @date: 2024/11/26 上午9:37
 */
public class Singleton {
    // 私有构造方法
    private Singleton(){}
    // 定义一个静态内部类
    private static class SingletonHolder{
        // 在内部类中声明并初始化外部类的对象
        // 为了防止外界对该静态属性进行修改，故在其上加了一个final关键字，也即意味着它就是一个常量了
        private static final Singleton INSTANCE = new Singleton();
    }
    // 提供公共的访问方式
    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
    /*上面我为大家讲解了双重检查锁这种单例实现方式，不过实现代码写起来还是稍微有点麻烦的，所以，在这一小节，我就来为大家介绍懒汉式的第四种实现方式，即静态内部类的方式。
    静态内部类单例模式中实例由内部类创建，由于JVM在加载外部类的过程中，是不会加载静态内部类的，只有内部类的属性或者方法被调用时才会被加载，
    并初始化其静态属性。当然，这个静态属性所要被赋予的值其实就是外部类的对象。
    而且，由于该静态属性被static修饰了，所以保证其只会被实例化一次，这样，就严格保证了实例化顺序，顺便就解决了上面所说的指令重排序的问题。
    */

    /*至此，静态内部类的这种实现方式我就给大家讲解完了。
    那么，我们是在何时何地创建外部类的对象的啊？是在内部类里面声明了一个静态的外部类类型的属性之后再对其进行的初始化。
    由于我们是在外部类里面定义了一个静态内部类，所以当我们在getInstance方法里面通过内部类类名调用其静态属性时，
    JVM才会去加载该内部类，并且初始化其静态属性。这样，该静态属性就只会被初始化一次了，
    即使是在多线程情况下调用getInstance方法，最终获取到的都是同一个对象。
    最后，我们可以简单的做一个总结，静态内部类单例模式是一种优秀的单例模式，是开源项目中比较常用的一种单例模式。在没有加任何锁的情况下，
    保证了多线程下的安全，并且没有任何性能影响和空间的浪费。*/
}
